home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mint99s / xbios.c < prev    next >
C/C++ Source or Header  |  1992-12-23  |  6KB  |  264 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * XBIOS replacement routines
  9.  */
  10.  
  11. #include "mint.h"
  12.  
  13. extern int tosvers;    /* from main.c */
  14.  
  15. #define XBIOS_MAX 0x80
  16.  
  17. Func xbios_tab[XBIOS_MAX];    /* initially all zeros */
  18. short xbios_max = XBIOS_MAX;
  19.  
  20. /* NOTE: has_bconmap is initialized in main.c */
  21.  
  22. int has_bconmap;    /* flag: set if running under a version
  23.              * of TOS which supports Bconmap
  24.              */
  25.  
  26. /*
  27.  * Supexec() presents a lot of problems for us: for example, the user
  28.  * may be calling the kernel, or may be changing interrupt vectors
  29.  * unexpectedly. So we play some dirty tricks here: the function
  30.  * call is treated like a signal handler, and we take advantage
  31.  * of the fact that no context switches will take place while
  32.  * in supervisor mode. ASSUMPTION: the user will not choose to
  33.  * switch back to user mode, or if s/he does it will be as part
  34.  * of a longjmp().
  35.  *
  36.  * BUG: if the user function switches to user mode, then back to
  37.  * supervisor mode and returns, then the returned value may be
  38.  * inaccurate (this happens if two programs make Supexec calls
  39.  * at the same time).
  40.  */
  41.  
  42. static long ARGS_ON_STACK (*usrcall) P_((long, long,long,long,long,long));
  43. static long usrret;
  44. static long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
  45.  
  46. static void ARGS_ON_STACK do_usrcall P_((void));
  47.  
  48. static void ARGS_ON_STACK
  49. do_usrcall()
  50. {
  51.     usrret = (*usrcall)((long)usrcall, usrarg1, usrarg2, usrarg3, usrarg4,
  52.          usrarg5);
  53. }
  54.  
  55. long ARGS_ON_STACK
  56. supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
  57.     Func funcptr;
  58.     long arg1, arg2, arg3, arg4, arg5;
  59. {
  60.     short savesr;
  61.     CONTEXT *syscall = &curproc->ctxt[SYSCALL];
  62.  
  63. /* set things up so that "signal 0" will be handled by calling the user's
  64.  * function.
  65.  */
  66.  
  67.     usrcall = funcptr;
  68.     usrarg1 = arg1;
  69.     usrarg2 = arg2;
  70.     usrarg3 = arg3;
  71.     usrarg4 = arg4;
  72.     usrarg5 = arg5;
  73.     curproc->sighandle[0] = (long)do_usrcall;
  74.     savesr = syscall->sr;    /* save old super/user mode flag */
  75.     syscall->sr |= 0x2000;    /* set supervisor mode */
  76.     handle_sig(0);        /* actually call out to the user function */
  77.     syscall->sr = savesr;
  78.  
  79. /* do_usrcall saves the user's return value in usrret */
  80.     return usrret;
  81. }
  82.  
  83.  
  84. /*
  85.  * midiws: we have to replace this, because it's possible that the process'
  86.  * view of what the MIDI port is has been changed by Fforce or Fmidipipe
  87.  */
  88.  
  89. long ARGS_ON_STACK
  90. midiws(cnt, buf)
  91.     int cnt;
  92.     const char *buf;
  93. {
  94.     FILEPTR *f;
  95.     long towrite = cnt+1;
  96.  
  97.     f = curproc->handle[-5];    /* MIDI output handle */
  98.     if (!f) return EIHNDL;
  99.  
  100.     if (is_terminal(f)) {
  101.         while (cnt >= 0) {
  102.             tty_putchar(f, (long)*buf, RAW);
  103.             buf++; cnt--;
  104.         }
  105.         return towrite;
  106.     }
  107.     return (*f->dev->write)(f, buf, towrite);
  108. }
  109.  
  110. /*
  111.  * Modem control things: these are replaced because we handle
  112.  * Bconmap ourselves
  113.  */
  114.  
  115. /* mapin: utility routine, does a Bconmap and keeps track
  116.  * so we call the kernel only when necessary; call this
  117.  * only if has_bconmap is "true".
  118.  * Returns: 0 on failure, 1 on success.
  119.  */
  120. int curbconmap;
  121.  
  122. int
  123. mapin(dev)
  124.     int dev;
  125. {
  126.     long r;
  127.  
  128.     if (dev == curbconmap)
  129.         return 1;
  130.     r = Bconmap(dev);
  131.     if (r) {
  132.         curbconmap = dev;
  133.         return 1;
  134.     }
  135.     return 0;
  136. }
  137.     
  138. long ARGS_ON_STACK
  139. uiorec(dev)
  140.     int dev;
  141. {
  142.     TRACE(("Iorec(%d)", dev));
  143.     if (dev == 0 && has_bconmap)
  144.         mapin(curproc->bconmap);
  145.     return (long)Iorec(dev);
  146. }
  147.  
  148. long ARGS_ON_STACK
  149. rsconf(baud, flow, uc, rs, ts, sc)
  150.     int baud, flow, uc, rs, ts, sc;
  151. {
  152.     long rsval;
  153.     static int oldbaud = -1;
  154.     int ret_oldbaud = 0;
  155.     IOREC_T *ior;
  156.  
  157.     TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
  158.         uc, rs, ts, sc));
  159.  
  160.     if (has_bconmap)
  161.         mapin(curproc->bconmap);
  162.  
  163. #ifndef DONT_ONLY030_THIS
  164. /* Note: in theory, the code below shouldn't be necessary
  165. if we're running on a 68030 chip; after all, in such a case
  166. we MUST have TOS 1.6 or better...
  167. However, the code breaks if we comment this out, even though
  168. tosvers is indeed > 0x0104. Must be a compiler bug, but it's
  169. nothing obvious!
  170. */
  171.  
  172. /*
  173.   If this is an old TOS, try to rearrange things to support
  174.   the following Rsconf() features:
  175.     1. Rsconf(-2, ...) does not return current baud (it crashes)
  176.         -> keep track of old speed in static variable
  177.     2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
  178.         -> make speed parameter -1 if new speed matches old speed
  179.     3. Rsconf() discards any buffered output
  180.         -> use Iorec() to ensure all buffered data was sent before call
  181. */
  182.     else if (tosvers < 0x0104) {
  183.         if (baud == -2) {
  184.             ret_oldbaud = 1;
  185.             baud = -1;
  186.         } else if (baud == oldbaud)
  187.             baud = -1;
  188.         else if (baud > -1)
  189.             oldbaud = baud;
  190.     }
  191. /* This part _is_ necessary on TOS 1.04 */
  192.     if (tosvers <= 0x0104) {
  193.         ior = ((IOREC_T *) uiorec(0)) + 1; /* output record */
  194.         while (ior->head != ior->tail) {
  195.             TRACE(("Rsconf() napping until transmit buf empty"));
  196.             nap(200);
  197.         }
  198.     }
  199. #endif /* ONLY030 */
  200.  
  201.     rsval = Rsconf(baud, flow, uc, rs, ts, sc);
  202.     if (ret_oldbaud)
  203.         rsval = (long) oldbaud;
  204.  
  205.     return rsval;
  206. }
  207.  
  208. long ARGS_ON_STACK
  209. bconmap(dev)
  210.     int dev;
  211. {
  212.     int old = curproc->bconmap;
  213.  
  214.     TRACE(("Bconmap(%d)", dev));
  215.  
  216.     if (has_bconmap) {
  217.         if (dev == -1) return old;
  218.         if (dev == -2) return Bconmap(-2);
  219.         if (dev == 0) return 0;  /* the user's just testing */
  220.         if (mapin(dev) == 0) {
  221.             DEBUG(("Bconmap: mapin(%d) failed", dev));
  222.             return 0;
  223.         }
  224.         if (set_auxhandle(curproc, dev) == 0) {
  225.             DEBUG(("Bconmap: Couldn't change AUX:"));
  226.             return 0;
  227.         }
  228.         curproc->bconmap = dev;
  229.         return old;
  230.     }
  231.     return EINVFN;    /* no Bconmap available */
  232. }
  233.  
  234. /*
  235.  * cursconf(): this gets converted into an ioctl() call on
  236.  * the appropriate device
  237.  */
  238.  
  239. long ARGS_ON_STACK
  240. cursconf(cmd, op)
  241.     int cmd, op;
  242. {
  243.     FILEPTR *f;
  244.  
  245.     f = curproc->handle[-1];
  246.     if (!f || !is_terminal(f))
  247.         return EINVFN;
  248.     return
  249.       (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
  250. }
  251.  
  252. void
  253. init_xbios()
  254. {
  255.     curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
  256.  
  257.     xbios_tab[0x0c] = midiws;
  258.     xbios_tab[0x0e] = uiorec;
  259.     xbios_tab[0x0f] = rsconf;
  260.     xbios_tab[0x15] = cursconf;
  261.     xbios_tab[0x26] = supexec;
  262.     xbios_tab[0x2c] = bconmap;
  263. }
  264.